home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
util
/
misc
/
ManBrowser1_1.lha
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-07
|
15KB
|
630 lines
/************************************************************************/
/* */
/* Copyright (C) 1994 Christian Stieber */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/************************************************************************/
/* */
/* Author address: */
/* Christian Stieber */
/* Konradstraße 41 */
/* D-85055 Ingolstadt */
/* (Germany) */
/* Phone: 0841-59896 */
/* */
/************************************************************************/
#ifndef V39
#define CreatePool LibCreatePool
#define DeletePool LibDeletePool
#define AllocPooled LibAllocPooled
#define FreePooled LibFreePooled
#endif
#ifndef DOS_DOSEXTENS_H
#include <dos/dosextens.h>
#endif
#ifndef DOS_EXALL_H
#include <dos/exall.h>
#endif
#ifndef INTUITION_INTUITION_H
#include <intuition/intuition.h>
#endif
#ifndef LIBRARIES_AMIGAGUIDE_H
#include <libraries/amigaguide.h>
#endif
#ifndef WORKBENCH_STARTUP_H
#include <workbench/startup.h>
#endif
#ifndef WORKBENCH_WORKBENCH_H
#include <workbench/workbench.h>
#endif
#ifndef __GNUC__
#ifndef CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#endif
#ifndef CLIB_DOS_PROTOS_H
#include <clib/dos_protos.h>
#endif
#ifndef CLIB_UTILITY_PROTOS_H
#include <clib/utility_protos.h>
#endif
#ifndef CLIB_INTUITION_PROTOS_H
#include <clib/intuition_protos.h>
#endif
#ifndef CLIB_ICON_PROTOS_H
#include <clib/icon_protos.h>
#endif
#ifndef CLIB_AMIGAGUIDE_PROTOS_H
#include <clib/amigaguide_protos.h>
#endif
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/amigaguide_pragmas.h>
#endif
#include <string.h>
#include "Globals.h"
/***********************************************/
struct DosLibrary *DOSBase;
struct IntuitionBase *IntuitionBase;
struct Library *AmigaGuideBase;
struct Library *UtilityBase;
/***********************************************/
#ifdef __GNUC__
#include "Inlines.h"
#ifndef V39
APTR AllocPooled (APTR, ULONG);
void FreePooled (APTR, APTR, ULONG);
APTR CreatePool (ULONG, ULONG, ULONG);
void DeletePool (APTR);
#endif
#endif /* __GNUC__ */
/***********************************************/
#define CONFIGFILE "ManualBrowser.config"
/***********************************************/
char Version[] = "$VER: ManualBrowser " PROGVERSION " (" PROGDATE ")"
#ifdef V39
"(V39) "
#endif
"(" CPU ") "
"© 1994 Christian Stieber";
/***********************************************/
#define BASENAME "ManBrowser"
#define PUDDLESIZE (20*1024)
/***********************************************/
struct ActionNode *ActionList;
BPTR ManDir;
long LineLength = 70;
char DatabaseName[64];
/***********************************************/
static void *MemoryPool;
static AMIGAGUIDEHOST AmigaGuideHostHandle;
static AMIGAGUIDECONTEXT AmigaGuideHandle;
static char Filename[64];
static BPTR FileHandle;
static struct WBStartup *WBStartupMessage;
static struct EasyStruct EasyStruct =
{
5 * 4,
0,
"Manual browser " PROGVERSION " error",
NULL,
NULL
};
/***********************************************/
#ifdef __GNUC__
static void
MyExit (int) __attribute__ ((noreturn));
#endif
static void MyExit (int RC)
{
if (WBStartupMessage)
{
Forbid ();
ReplyMsg ((struct Message *) WBStartupMessage);
}
exit (RC);
}
/************************************************************************/
/* */
/* Malloc() */
/* */
/************************************************************************/
void *
Malloc (ULONG Size)
{
ULONG *Memory;
Size += 4;
if (Memory = AllocPooled (MemoryPool, Size))
{
*Memory = Size;
Memory++;
}
return Memory;
}
/************************************************************************/
/* */
/* Free() */
/* */
/************************************************************************/
void
Free (void *Memory)
{
if (Memory)
{
FreePooled (MemoryPool, ((ULONG *) Memory) - 1, *(((ULONG *) Memory) - 1));
}
}
/***********************************************/
static void
DisplayError (char *Format,...)
{
if (WBStartupMessage)
{
EasyStruct.es_TextFormat = Format;
EasyStruct.es_GadgetFormat = "Quit";
EasyRequestArgs (NULL, &EasyStruct, NULL, (&Format) + 1);
}
else
{
VPrintf (Format, (&Format) + 1);
PutStr ("\n");
}
}
/***********************************************/
static void
DisplayDosError (char *Filename)
{
if (WBStartupMessage)
{
char Buffer[256];
char *t;
t = Buffer;
Fault (IoErr (), Filename, t, sizeof (Buffer));
EasyStruct.es_TextFormat = "%s";
EasyStruct.es_GadgetFormat = "Quit";
EasyRequestArgs (NULL, &EasyStruct, NULL, &t);
}
else
{
PrintFault (IoErr (), Filename);
}
}
/***********************************************/
#ifdef __GNUC__
static void
CloseAll (int) __attribute__ ((noreturn));
#endif
static void CloseAll (int RC)
{
if (AmigaGuideHandle)
CloseAmigaGuide (AmigaGuideHandle);
if (AmigaGuideHostHandle)
{
while (RemoveAmigaGuideHostA (AmigaGuideHostHandle, NULL))
{
Delay (TICKS_PER_SECOND);
}
}
if (FileHandle)
{
DeleteFile (Filename);
}
if (ManDir)
UnLock (ManDir);
if (MemoryPool)
DeletePool (MemoryPool);
CloseLibrary (AmigaGuideBase);
CloseLibrary (UtilityBase);
CloseLibrary ((struct Library *) IntuitionBase);
CloseLibrary ((struct Library *) DOSBase);
MyExit (RC);
}
/***********************************************/
static void
InitThings (void)
{
struct Process *MyProcess;
MyProcess = (struct Process *) FindTask (NULL);
if (MyProcess->pr_CLI)
{
WBStartupMessage = NULL;
}
else
{
do
{
WaitPort (&MyProcess->pr_MsgPort);
}
while (!(WBStartupMessage = (struct WBStartup *) GetMsg (&MyProcess->pr_MsgPort)));
}
#ifdef V39
if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 39)))
#else
if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
#endif
{
MyExit (100);
}
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 37)))
{
CloseLibrary ((struct Library *) DOSBase);
MyExit (100);
}
if (!(UtilityBase = OpenLibrary ("utility.library", 37)))
{
DisplayError ("Unable to open utility.library V37");
CloseAll (RETURN_FAIL);
}
if (!(AmigaGuideBase = OpenLibrary ("amigaguide.library", 34)))
{
DisplayError ("Unable to open amigaguide.library V34");
CloseAll (RETURN_FAIL);
}
if (!(MemoryPool = CreatePool (0, PUDDLESIZE, PUDDLESIZE)))
{
DisplayError ("Unable to create memory pool");
CloseAll (RETURN_FAIL);
}
}
/***********************************************/
static void
AddDatabase (void)
{
#ifdef __GNUC__
static struct Hook AmigaGuideHook =
{
{NULL, NULL},
HookEntryA1,
AmigaGuideHostDispatcher,
NULL
};
#else
static struct Hook AmigaGuideHook =
{
{NULL, NULL},
AmigaGuideHostDispatcher,
NULL,
NULL
};
#endif
char *t;
Sprintf (DatabaseName, BASENAME ".%lx", FindTask (NULL));
Sprintf (Filename, "t:%s.guide", DatabaseName);
if (!(FileHandle = Open (Filename, MODE_NEWFILE)))
{
DisplayDosError (Filename);
CloseAll (RETURN_ERROR);
}
t = DatabaseName;
if (VFPrintf (FileHandle, "@database %s.guide\n"
"@node EnItSiRhC\n"
"@endnode\n", &t) == -1)
{
DisplayDosError (Filename);
Close (FileHandle);
CloseAll (RETURN_ERROR);
}
Close (FileHandle);
if (!(AmigaGuideHostHandle = AddAmigaGuideHostA (&AmigaGuideHook, DatabaseName, NULL)))
{
DisplayError ("Unable to add dynamic amiga guide host");
CloseAll (RETURN_FAIL);
}
}
/***********************************************/
static void
OpenDatabase (void)
{
struct NewAmigaGuide NewAmigaGuide;
NewAmigaGuide.nag_Lock = NULL;
NewAmigaGuide.nag_Name = Filename;
NewAmigaGuide.nag_Screen = NULL;
NewAmigaGuide.nag_PubScreen = NULL;
NewAmigaGuide.nag_HostPort = NULL;
NewAmigaGuide.nag_ClientPort = BASENAME;
NewAmigaGuide.nag_BaseName = BASENAME;
NewAmigaGuide.nag_Flags = HTF_NOACTIVATE;
NewAmigaGuide.nag_Context = NULL;
NewAmigaGuide.nag_Node = NULL;
NewAmigaGuide.nag_Line = 0;
NewAmigaGuide.nag_Extens = NULL;
NewAmigaGuide.nag_Client = NULL;
if (!(AmigaGuideHandle = OpenAmigaGuideA (&NewAmigaGuide, NULL)))
{
DisplayError ("Unable to open amiga guide database");
CloseAll (RETURN_FAIL);
}
}
/***********************************************/
#ifdef __GNUC__
#define ICONBASE IconBase,
#else
#define ICONBASE
#endif
static void
GetParams (void)
{
if (WBStartupMessage)
{
struct Library *IconBase;
if ((IconBase = OpenLibrary ("icon.library", 33)))
{
if (WBStartupMessage->sm_NumArgs)
{
BPTR OldCurrDir;
struct DiskObject *DiskObject;
OldCurrDir = CurrentDir (WBStartupMessage->sm_ArgList[0].wa_Lock);
if ((DiskObject = GetDiskObject (ICONBASE WBStartupMessage->sm_ArgList[0].wa_Name)))
{
char *ManPath;
if (!((ManPath = FindToolType (ICONBASE (UBYTE **) DiskObject->do_ToolTypes, "MANUALDIR")) ||
(ManPath = FindToolType (ICONBASE (UBYTE **) DiskObject->do_ToolTypes, "MANDIR")) ||
(ManPath = FindToolType (ICONBASE (UBYTE **) DiskObject->do_ToolTypes, "DIR"))))
{
ManPath = "man:";
}
if (!(ManDir = Lock (ManPath, SHARED_LOCK)))
{
DisplayDosError (ManPath);
}
FreeDiskObject (ICONBASE DiskObject);
}
CurrentDir (OldCurrDir);
}
CloseLibrary (IconBase);
}
}
else
{
struct
{
char *ManualDir;
}
Arguments;
struct RDArgs *RDArgs;
Arguments.ManualDir = "man:";
if (!(RDArgs = ReadArgs ("MANUALDIR=MANDIR=DIR", (long *) &Arguments, NULL)))
{
PrintFault (IoErr (), NULL);
CloseAll (RETURN_FAIL);
}
if (!(ManDir = Lock (Arguments.ManualDir, SHARED_LOCK)))
{
DisplayDosError (Arguments.ManualDir);
}
FreeArgs (RDArgs);
}
if (!ManDir)
{
CloseAll (RETURN_FAIL);
}
}
/***********************************************/
int
ReadConfigFile (BPTR ConfigFile, struct ActionNode **ActionList)
{
BPTR OldInput;
OldInput = SelectInput (ConfigFile);
while (TRUE)
{
struct
{
char *Pattern;
char *Action;
}
CurrentLine;
struct RDArgs *LineArgs;
while (TRUE)
{
int Character;
Character = FGetC (ConfigFile);
if (Character != '\n' && Character != ' ' && Character != '\t')
{
if (Character == -1)
{
if (IoErr ())
{
return FALSE;
}
SelectInput (OldInput);
return TRUE;
}
UnGetC (ConfigFile, Character);
break;
}
}
CurrentLine.Pattern = NULL;
CurrentLine.Action = NULL;
if (LineArgs = ReadArgs ("P/A,A/A/F", (long *) &CurrentLine, NULL))
{
struct ActionNode *ActionNode;
int AllocSize, PatternSize;
PatternSize = 2 * strlen (CurrentLine.Pattern);
AllocSize = sizeof (struct ActionNode) + strlen (CurrentLine.Action) + PatternSize;
if ((ActionNode = Malloc (AllocSize)))
{
ActionNode->Pattern = Stpcpy (ActionNode->Action, CurrentLine.Action) + 1;
if (ParsePatternNoCase (CurrentLine.Pattern, ActionNode->Pattern, PatternSize) != -1)
{
ActionNode->Next = *ActionList;
*ActionList = ActionNode;
}
else
{
DisplayError ("Error in pattern: %s", CurrentLine.Pattern);
ActionNode = NULL;
}
}
FreeArgs (LineArgs);
if (!ActionNode)
{
return FALSE;
}
}
else
{
return FALSE;
}
}
/* Not reached */
}
/***********************************************/
static void
ReadConfig (void)
{
static char *ConfigFile[] =
{
"PROGDIR:" CONFIGFILE,
"S:" CONFIGFILE,
"ENV:" CONFIGFILE
};
int i;
for (i = 0; i < 3; i++)
{
BPTR FileHandle;
if ((FileHandle = Open (ConfigFile[i], MODE_OLDFILE)))
{
int Result;
Result = ReadConfigFile (FileHandle, &ActionList);
Close (FileHandle);
if (!Result)
{
DisplayDosError (ConfigFile[i]);
CloseAll (RETURN_FAIL);
}
}
}
}
/***********************************************/
void Main (void);
void
Main (void)
{
InitThings ();
GetParams ();
ReadConfig ();
AddDatabase ();
OpenDatabase ();
CloseAll (RETURN_OK);
/* Not reached */
}